<?php
/**	
*	FILENAME: 		/libraries/webct.php
*	DESCRIPTION:	This library that uses the PHP Snoopy library to interact with Villanova's WebCT system.
*	AUTHOR:			Casey Burkhardt
*	VERSION:		1.0.0
*	LAST MODIFIED:	12/30/2009
**/

/**
	THIS SCRIPT IS UNSTABLE AND SITLL UNDER DEVELOPMENT.
	ITS USE IS EXPERIMENTAL AND SHOULD NOT BE USED IN PRODUCTION AT THIS TIME.
**/
die();

require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");

function parseCookie($val) {
	$equalsSign = strpos($val, "=");
	$cookieName = substr($val, strlen("Set-Cookie: "), $equalsSign - strlen("Set-Cookie: "));
	$semiColon = strpos($val, ";");
	$cookieValue = substr($val, $equalsSign + 1, $semiColon - $equalsSign - 1);
	$result[$cookieName] = $cookieValue;
	return $result;
}

/**	
*	DESCRIPTION:	Returns a webCT authentication token.
**/
function getWebCTAuthenticationToken($userName, $password) {
	// Create a new instance of Snoopy, the page fetching / parsing engine.
	$mainPage = new Snoopy;
	// Set a timeout, in case this thing doesn't work
	$mainPage -> read_timeout = 2;
	// We will need to fetch pages using HTTPS, so we must point Snoopy to our instance of curl.
	// This information is stored in our environment configuration.
	$mainPage -> curl_path = getCurlPath();
	// Set up appropriate Header Types, We'll reuse these...
	$rawHeaders["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
	$rawHeaders["Accept-Language"] = "en-us,en;q=0.5";
	$rawHeaders["Accept-Encoding"] = "gzip,deflate";
	$rawHeaders["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.7";
	$rawHeaders["Keep-Alive"] = "300";
	$rawHeaders["Connection"] = "keep-alive";
	$mainPage -> rawheaders = $rawHeaders;
	
	// We need to get an initial session cookies from WebCT... I can tell this is going to be a pain already.
	// Let's just request the main page.
	echo "<br /> Requesting WebCT Main Page: <br />";
	
	if ($mainPage -> fetch("https://elearning.villanova.edu")) {
		while(list($key,$val) = each($mainPage->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$mainPage -> cookies = array_merge(parseCookie($val), $mainPage -> cookies);
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($mainPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$mainPage->error."\n";
		die();
	}
	$cookiesSoFar = $mainPage -> cookies;
	
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// Now we need to fetch the WebCT Insertion Page
	$insertionPage = new Snoopy;
	$insertionPage -> read_timeout = 2;
	$insertionPage -> curl_path = getCurlPath();
	$insertionPage -> cookies = $cookiesSoFar;
	$insertionPage -> rawheaders = $rawHeaders;

	echo "<br />Requesting the WebCT Insertion Page: <br />";
	if ($insertionPage -> fetch("https://elearning.villanova.edu/webct/entryPageIns.dowebct")) {
		while(list($key,$val) = each($insertionPage->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$insertionPage -> cookies = array_merge(parseCookie($val), $insertionPage -> cookies);
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($insertionPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$insertionPage->error."\n";
		die();
	}
	$cookiesSoFar = $insertionPage -> cookies;

	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";

	// Now we're going to hit up the WebCT Login Form.
	// But, we actually do this with a POST Request...
	// WebCT people are retards who don't understand HTTP standards...
	$postVars["insId"] = "102089011";
	$postVars["glcid"] = "URN%3AX-WEBCT-VISTA-V1%3A1468da52-9968-0617-0113-9c275d9d136f";
	$postVars["newUserGlcid"] = "URN%3AX-WEBCT-VISTA-V1%3A1468da52-9968-0617-0113-9c275d9d136f";
	$postVars["insName"] = "Villanova University";
	$postVars["actionType"] = "";
	
	$loginPage = new Snoopy;
	$loginPage -> read_timeout = 2;
	$loginPage -> curl_path = getCurlPath();
	$loginPage -> cookies = $cookiesSoFar;
	$loginPage -> rawheaders = $rawHeaders;
	
	echo "<br />Requesting the WebCT Logon Page: <br />";
	if ($loginPage -> submit("https://elearning.villanova.edu/webct/logonDisplay.dowebct", $postVars)) {
		while(list($key,$val) = each($loginPage->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$loginPage -> cookies = array_merge(parseCookie($val), $loginPage -> cookies);
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($loginPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$loginPage->error."\n";
		die();		
	}
	$cookiesSoFar = $loginPage -> cookies;
	
	
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	
	// Let's set some WebCT Login Variables... FML
	$submitVars["insId"] = "102089011";
	$submitVars["glcid"] = "URN:X-WEBCT-VISTA-V1:1468da52-9968-0617-0113-9c275d9d136f";
	$submitVars["newUserGlcid"] = "URN:X-WEBCT-VISTA-V1:1468da52-9968-0617-0113-9c275d9d136f";
	$submitVars["insName"] = "Villanova University";
	$submitVars["gotoid"] = "";
	$submitVars["actionType"] = "";
	$submitVars["webctid"] = $userName;
	$submitVars["timeZoneOffset"] = "5";
	$submitVars["password"] = $password;
	$submitVars[""] = "OK";
	
	// Submit the Login Form
	$loginSubmission = new Snoopy;
	$loginSubmission -> read_timeout = 2;
	$loginSubmission -> curl_path = getCurlPath();
	$loginSubmission -> cookies = $cookiesSoFar;
	$loginSubmission -> rawheaders = $rawHeaders;
	
	echo "<br />Submitting the WebCT Logon Page: <br />";
	if ($loginSubmission -> submit("https://elearning.villanova.edu/webct/urw/lc102089011.tp0/authenticateUser.dowebct", $submitVars)) {
		while(list($key,$val) = each($loginSubmission->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$loginSubmission -> cookies = array_merge(parseCookie($val), $loginSubmission -> cookies);
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($loginSubmission->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$loginSubmission->error."\n";
		die();		
	}
	$cookiesSoFar = $loginSubmission -> cookies;

	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";

	// From the HTTP 302 request that was received, the resulting URL must now be parsed, so we can determine the next request location.
	$startIndex = strpos($loginSubmission -> results, "https://");
	$endIndex = strpos($loginSubmission -> results, '"', $startIndex);
	$url = substr($loginSubmission -> results, $startIndex, $endIndex - $startIndex);
 
	// The response to our request contained in invalid URL.  Figures, those WebCT folks at Blackboard are real geniuses...
	// The :80 port designator is redundant as https:// protocol is provided.
	// We'll strip this and use port 443 instead.
	$url = str_replace(":80", "", $url);

	// We're about to make another request... Let's move the output up a bit.
	echo "<br /><br /><br />ASSHOLE REQUEST:<br /><br /><br />\n";

	// Some debugging...
	echo "Requesting: ". $url . "<br />With Cookies: ";
	print_r($cookiesSoFar);
	echo "<br /><br />";

	$authenticatedPage = new Snoopy;
	$authenticatedPage -> read_timeout = 2;
	$authenticatedPage -> curl_path = getCurlPath();
	$authenticatedPage -> cookies = $cookiesSoFar;
	$authenticatedPage -> rawheaders = $rawHeaders;
	
	if ($authenticatedPage -> fetch($url)) {
		while(list($key,$val) = each($authenticatedPage->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$authenticatedPage -> cookies = array_merge(parseCookie($val), $authenticatedPage -> cookies);
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($authenticatedPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$authenticatedPage->error."\n";
		die();		
	}
	$cookiesSoFar = $authenticatedPage -> cookies;
	
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
}
?>